package com.tzpay.tzpay.presenter;

import android.content.Context;

import com.tzpay.tzpay.R;
import com.tzpay.tzpay.api.IOnUploadOrderInfo;
import com.tzpay.tzpay.api.OrderCreate;
import com.tzpay.tzpay.api.OrderCreateRequest;
import com.tzpay.tzpay.api.OrderQuery;
import com.tzpay.tzpay.api.OrderQueryRequest;
import com.tzpay.tzpay.api.OrderRefundRequest;
import com.tzpay.tzpay.api.OrderReverseRequest;
import com.tzpay.tzpay.api.ResponseDataWrapper;
import com.tzpay.tzpay.api.TzBaseResponse;
import com.tzpay.tzpay.api.TzOrderCreate;
import com.tzpay.tzpay.api.TzOrderCreateResp;
import com.tzpay.tzpay.api.UploadOrderRequest;
import com.tzpay.tzpay.api.service.OrderService;
import com.tzpay.tzpay.api.service.TzService;
import com.tzpay.tzpay.bean.OrderInfo;
import com.tzpay.tzpay.common.BaseCallBack;
import com.tzpay.tzpay.db.OrderDBUtil;

import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit2Instance;

/**
 * 从服务器获取随机订单号
 * <p/>
 * 由订单号去翼支付平台创建订单
 * <p/>
 * Created by chenfeiyue on 16/3/18.
 */
public class TradePresenter implements Presenter, IOnUploadOrderInfo {
    private static final java.lang.String TAG = "TradePresenter";
    private TradeLogicView logicView;
    private IOnUploadOrderInfo uploadOrderInfo;
    private Context context;
    private OrderService orderService;

    private boolean isOnDestory = false;

    private TzService service;

    public TradePresenter(TradeLogicView logicView) {
        this.logicView = logicView;
        context = logicView.getContext();
        orderService = Retrofit2Instance.create(OrderService.class);
        setUploadOrderInfo(TradePresenter.this);
    }

    public void setUploadOrderInfo(IOnUploadOrderInfo uploadOrderInfo) {
        this.uploadOrderInfo = uploadOrderInfo;
    }

    /**
     * 创建订单
     *
     * @param barcode
     * @param amount
     */
    public void orderCreate(String barcode, String amount, String orderNo, String orderReqNo) {
        logicView.showProgress(TradeLogicView.TYPE_CREATE);
        OrderCreateRequest createRequest = new OrderCreateRequest();
        // TODO
        createRequest.setOrderNo(orderNo);
        createRequest.setOrderReqNo(orderReqNo);
        createRequest.barcode = barcode;
        createRequest.orderAmt = amount;
        createRequest.productAmt = amount;
        createRequest.mac = createRequest.calculateMac();

        Call<ResponseDataWrapper<OrderCreate>> order = orderService.orderCreate(createRequest.merchantId,
                createRequest.subMerchantId,
                createRequest.barcode, createRequest.orderNo, createRequest.orderReqNo, createRequest.channel,
                createRequest.busiType, createRequest.orderDate, createRequest.orderAmt, createRequest.productAmt,
                createRequest.attachAmt, createRequest.goodsName, createRequest.storeId, createRequest.backUrl,
                createRequest.ledgerDetail, createRequest.attach, createRequest.mac);
        OrderCreateCallBack createCallBack = new OrderCreateCallBack(TradePresenter.this, createRequest);
        order.enqueue(createCallBack);
    }

    /**
     * 订单查询
     *
     * @param orderNo
     * @param orderReqNo
     */
    public void orderQuery(String orderNo, String orderReqNo) {
        logicView.showProgress(TradeLogicView.TYPE_QUERY);
        OrderQueryRequest request = new OrderQueryRequest();
        request.orderNo = orderNo;  // 下单返回
        request.orderReqNo = orderReqNo;  // 下单返回
        request.mac = request.calculateMac();
        Call<ResponseDataWrapper<OrderQuery>> order = orderService.orderQuery(request.merchantId,
                request.orderNo, request.orderReqNo, request.orderDate, request.mac);
        // 取本地数据库中订单信息，
        OrderInfo orderInfo = getOrderInfoByNo(orderNo);
        OrderQueryCallBack queryCallBack = new OrderQueryCallBack(TradePresenter.this);
        queryCallBack.setOrderInfo(orderInfo);
        order.enqueue(queryCallBack);
    }

    /**
     * 撤销
     */
    public void orderRefund(String orderNo, String orderReqNo, String transAmt) {
        logicView.showProgress(TradeLogicView.TYPE_REFUND);
        OrderRefundRequest request = new OrderRefundRequest();
        request.oldOrderNo = orderNo;  // 下单返回 // 1458034665924
        request.oldOrderReqNo = orderReqNo;  // 下单返回
        request.transAmt = transAmt;
        request.mac = request.calculateMac();
        // {"result":null,"success":true,"errorCode":null,"errorMsg":null}
        // {"result":null,"success":false,"errorCode":"BE301010","errorMsg":"退款订单受理中，退款失败"}
        Call<ResponseDataWrapper<String>> order = orderService.orderRefund(request.merchantId, request.subMerchantId, request.merchantPwd,
                request.oldOrderNo, request.oldOrderReqNo, request.refundReqNo, request.refundReqDate,
                request.transAmt, request.channel, request.ledgerDetail, request.bgUrl, request.mac);

        OrderInfo orderInfo = getOrderInfoByNo(orderNo);
        orderInfo = OrderInfo.buildOrderInfo(orderInfo, request);
        OrderRefundCallBack refundCallBack = new OrderRefundCallBack(TradePresenter.this);
        refundCallBack.setOrderInfo(orderInfo);
        order.enqueue(refundCallBack);
    }

    /**
     * 冲正
     */
    public void orderReverse(String orderNo, String orderReqNo, String transAmt) {
        logicView.showProgress(TradeLogicView.TYPE_REFUND);
        OrderReverseRequest request = new OrderReverseRequest();
        request.oldOrderNo = orderNo;  // 下单返回 // 1458034665924
        request.oldOrderReqNo = orderReqNo;  // 下单返回
        request.transAmt = transAmt;
        request.mac = request.calculateMac();
        // {"result":null,"success":true,"errorCode":null,"errorMsg":null}
        // {"result":null,"success":false,"errorCode":"BE301010","errorMsg":"退款订单受理中，退款失败"}
        Call<ResponseDataWrapper<String>> order = orderService.orderReverse(request.merchantId, request.subMerchantId, request.merchantPwd,
                request.oldOrderNo, request.oldOrderReqNo, request.refundReqNo, request.refundReqDate,
                request.transAmt, request.channel, request.ledgerDetail, request.bgUrl, request.mac);

        OrderInfo orderInfo = getOrderInfoByNo(orderNo);
        orderInfo = OrderInfo.buildOrderInfo(orderInfo, request);
        OrderReverseCallBack reverseCallBack = new OrderReverseCallBack(TradePresenter.this);
        reverseCallBack.setOrderInfo(orderInfo);
        order.enqueue(reverseCallBack);
    }

    @Override
    public void onDestory() {
        isOnDestory = true;
    }

    @Override
    public void onUpload(OrderInfo info) {
        UploadOrderRequest request = UploadOrderRequest.buildUploadOrderRequest(info);
        if (request == null) {
            return;
        }
        if (service == null) {
            service = Retrofit2Instance.createRetrofit(TzService.TzBaseUrl).create(TzService.class);
        }
        Call<TzBaseResponse> uploadRequest = service.upload(request);
        UploadOrderInfoCallBack callBack = new UploadOrderInfoCallBack(TradePresenter.this);
        callBack.setOrderInfo(info);
        uploadRequest.enqueue(callBack);
    }

    /**
     * 上传订单
     *
     * @param orderInfo
     */
    private void uploadOrderInfo(OrderInfo orderInfo) {
        if (uploadOrderInfo != null)
            uploadOrderInfo.onUpload(orderInfo);
    }


    /**
     * 创建订单回调
     */
    private static final class OrderCreateCallBack extends BaseCallBack<TradePresenter, ResponseDataWrapper<OrderCreate>> {
        private OrderCreateRequest createRequest;

        public OrderCreateCallBack(TradePresenter presenter, OrderCreateRequest createRequest) {
            super(presenter);
            this.createRequest = createRequest;
        }

        @Override
        public void onResponseEx(TradePresenter presenter, Call<ResponseDataWrapper<OrderCreate>> call, Response<ResponseDataWrapper<OrderCreate>> response) {
            if (response == null || response.body() == null) {
                presenter.handleFail(TradeLogicView.TYPE_CREATE, presenter.context.getString(R.string.text_no_network));
                return;
            }
            ResponseDataWrapper<OrderCreate> orderWrapper = response.body();
            if (!orderWrapper.success) {
                presenter.handleFail(TradeLogicView.TYPE_CREATE, orderWrapper.errorMsg);
                // TODO 创建失败就不要保存上传了吧
                return;
            }

            // 组装订单信息加入数据库
            OrderInfo orderInfo = OrderInfo.buildOrderInfo(null, createRequest);
            orderInfo = OrderInfo.buildOrderInfo(orderInfo, orderWrapper.result);
            presenter.insert(orderInfo);

            // TODO
            presenter.uploadOrderInfo(orderInfo);
            presenter.handleSuccess(TradeLogicView.TYPE_CREATE, orderWrapper.result);
        }

        @Override
        public void onFailureEx(TradePresenter presenter, Call<ResponseDataWrapper<OrderCreate>> call, Throwable throwable) {
            presenter.handleFail(TradeLogicView.TYPE_CREATE, presenter.context.getString(R.string.text_no_network));
        }
    }


    /**
     * 查询订单回调
     */
    private static final class OrderQueryCallBack extends BaseCallBack<TradePresenter, ResponseDataWrapper<OrderQuery>> {
        private OrderInfo orderInfo;

        public OrderQueryCallBack(TradePresenter presenter) {
            super(presenter);
        }

        @Override
        public void onResponseEx(TradePresenter presenter, Call<ResponseDataWrapper<OrderQuery>> call, Response<ResponseDataWrapper<OrderQuery>> response) {
            if (response == null || response.body() == null) {
                presenter.handleFail(TradeLogicView.TYPE_QUERY, presenter.context.getString(R.string.text_no_network));
                // TODO
                presenter.uploadOrderInfo(orderInfo);
                return;
            }
            ResponseDataWrapper<OrderQuery> orderWrapper = response.body();
            if (!orderWrapper.success) {
                presenter.handleFail(TradeLogicView.TYPE_QUERY, orderWrapper.errorMsg);
                // TODO
                presenter.uploadOrderInfo(orderInfo);
                return;
            }
            final OrderInfo oldOrderInfo = orderInfo == null ? null : orderInfo.clone();
            orderInfo = OrderInfo.buildOrderInfo(orderInfo, orderWrapper.result);
            // OrderInfo不相同时插入数据库并上传，避免多次操作数据库
            if (oldOrderInfo == null || !oldOrderInfo.equals(orderInfo)) {
                presenter.updateOrInsert(orderInfo);
                // TODO
                presenter.uploadOrderInfo(orderInfo);
            }
            presenter.handleSuccess(TradeLogicView.TYPE_QUERY, orderWrapper.result);
        }

        @Override
        public void onFailureEx(TradePresenter presenter, Call<ResponseDataWrapper<OrderQuery>> call, Throwable throwable) {
            presenter.handleFail(TradeLogicView.TYPE_QUERY, presenter.context.getString(R.string.text_no_network));
        }

        public void setOrderInfo(OrderInfo orderInfo) {
            this.orderInfo = orderInfo;
        }
    }

    /**
     * 撤销订单回调
     */
    private static final class OrderRefundCallBack extends BaseCallBack<TradePresenter, ResponseDataWrapper<String>> {
        private OrderInfo orderInfo;

        public OrderRefundCallBack(TradePresenter presenter) {
            super(presenter);
        }

        public void setOrderInfo(OrderInfo orderInfo) {
            this.orderInfo = orderInfo;
        }

        @Override
        public void onResponseEx(TradePresenter presenter, Call<ResponseDataWrapper<String>> call, Response<ResponseDataWrapper<String>> response) {
            if (response == null || response.body() == null) {
                presenter.handleFail(TradeLogicView.TYPE_REFUND, presenter.context.getString(R.string.text_no_network));
                // TODO
                presenter.uploadOrderInfo(orderInfo);
                return;
            }
            ResponseDataWrapper<String> orderWrapper = response.body();
            if (!orderWrapper.success) {
                presenter.handleFail(TradeLogicView.TYPE_REFUND, orderWrapper.errorMsg);
                // TODO
                presenter.uploadOrderInfo(orderInfo);
                return;
            }

            // 撤销成功, 直接设置订单状态为已退款
            orderInfo.setRefundFlag(OrderInfo.FLAG_REFUNDED);
            // 不相同时插入数据库并上传
            presenter.updateOrInsert(orderInfo);

            // TODO
            presenter.uploadOrderInfo(orderInfo);
            presenter.handleSuccess(TradeLogicView.TYPE_REFUND, orderWrapper.result);
        }

        @Override
        public void onFailureEx(TradePresenter presenter, Call<ResponseDataWrapper<String>> call, Throwable throwable) {
            presenter.handleFail(TradeLogicView.TYPE_REFUND, presenter.context.getString(R.string.text_no_network));
        }
    }

    /**
     * 冲正订单回调
     */
    private static final class OrderReverseCallBack extends BaseCallBack<TradePresenter, ResponseDataWrapper<String>> {

        private OrderInfo orderInfo;

        public OrderReverseCallBack(TradePresenter presenter) {
            super(presenter);
        }

        public void setOrderInfo(OrderInfo orderInfo) {
            this.orderInfo = orderInfo;
        }

        @Override
        public void onResponseEx(TradePresenter presenter, Call<ResponseDataWrapper<String>> call, Response<ResponseDataWrapper<String>> response) {

            if (response == null || response.body() == null) {
                presenter.handleFail(TradeLogicView.TYPE_REVERSE, presenter.context.getString(R.string.text_no_network));
                // TODO
                presenter.uploadOrderInfo(orderInfo);
                // 查询订单状态
                presenter.orderQuery(orderInfo.getOrderNo(), orderInfo.getOrderReqNo());
                return;
            }
            ResponseDataWrapper<String> orderWrapper = response.body();
            if (!orderWrapper.success) {
                presenter.handleFail(TradeLogicView.TYPE_REVERSE, orderWrapper.errorMsg);
                // TODO
                presenter.uploadOrderInfo(orderInfo);

                // 查询订单状态
                presenter.orderQuery(orderInfo.getOrderNo(), orderInfo.getOrderReqNo());
                return;
            }
            // 冲正成功
            orderInfo.setRefundFlag(OrderInfo.FLAG_REFUNDED);
            presenter.updateOrInsert(orderInfo);
            presenter.handleSuccess(TradeLogicView.TYPE_REVERSE, orderWrapper.result);
            // TODO 查询订单状态
//            presenter.orderQuery(orderInfo.getOrderNo(), orderInfo.getOrderReqNo());
            // TODO
            presenter.uploadOrderInfo(orderInfo);
        }

        @Override
        public void onFailureEx(TradePresenter presenter, Call<ResponseDataWrapper<String>> call, Throwable throwable) {
            presenter.handleFail(TradeLogicView.TYPE_REVERSE, presenter.context.getString(R.string.text_no_network));
        }
    }


    private void handleFail(int type, String resperr) {
        if (isOnDestory) {
            return;
        }
        logicView.onFailed(type, resperr);
    }

    private void handleSuccess(int type, Object result) {
        if (isOnDestory) {
            return;
        }
        logicView.onSuccess(type, result);
    }


    /**
     * 修改数据库，没有数据则新增
     *
     * @param orderInfo
     */
    private void updateOrInsert(OrderInfo orderInfo) {
        OrderDBUtil.getInstance(context).updateOrInsert(orderInfo);
    }

    private void insert(OrderInfo orderInfo) {
        OrderDBUtil.getInstance(context).insert(orderInfo);
    }

    private OrderInfo getOrderInfoByNo(String orderNo) {
        return OrderDBUtil.getInstance(context).getOrderInfoByNo(orderNo);
    }


    /**
     * 从腾卓服务器获取orderNo
     */
    public void getOrderNoFormServer() {
        TzOrderCreate create = new TzOrderCreate();
        if (service == null) {
            service = Retrofit2Instance.createRetrofit(TzService.TzBaseUrl).create(TzService.class);
        }
        Call<TzOrderCreateResp> createCall = service.create(create);
        GetOrderNoCallBack callBack = new GetOrderNoCallBack(TradePresenter.this);
        createCall.enqueue(callBack);
    }

    /**
     * 获取orderNo回调
     */
    private static final class GetOrderNoCallBack extends BaseCallBack<TradePresenter, TzOrderCreateResp> {

        public GetOrderNoCallBack(TradePresenter presenter) {
            super(presenter);
        }

        @Override
        public void onResponseEx(TradePresenter presenter, Call<TzOrderCreateResp> call, Response<TzOrderCreateResp> response) {
            if (response == null || response.body() == null) {
                presenter.handleFail(TradeLogicView.TYPE_GET_ORDER_NO, presenter.context.getString(R.string.text_no_network));
                return;
            }
            TzOrderCreateResp body = response.body();
            if (!body.isSuccess()) {
                presenter.handleFail(TradeLogicView.TYPE_GET_ORDER_NO, body.getErrorMessage());
                return;
            }
            presenter.handleGetNoSuccess(TradeLogicView.TYPE_GET_ORDER_NO, body);
        }

        @Override
        public void onFailureEx(TradePresenter presenter, Call<TzOrderCreateResp> call, Throwable throwable) {
            presenter.handleFail(TradeLogicView.TYPE_GET_ORDER_NO, presenter.context.getString(R.string.text_no_network));
        }
    }

    private void handleGetNoSuccess(int type, TzOrderCreateResp response) {
        handleSuccess(type, response);
//        String responseStr = "{\"resMsg\":0,\"txNo\":" + RandomStringUtils.randomNumeric(16) + "}";
//        try {
//            response = new Gson().fromJson(responseStr, TzOrderCreateResp.class);
//            T.e(TAG, "---------> " + response.toString());
//            handleSuccess(type, response);
//        } catch (Exception e) {
//            e.printStackTrace();
//            handleFail(type, context.getString(R.string.text_no_network));
//        }
    }


    /**
     * 获取orderNo回调
     */
    private static final class UploadOrderInfoCallBack extends BaseCallBack<TradePresenter, TzBaseResponse> {

        private OrderInfo orderInfo;

        public UploadOrderInfoCallBack(TradePresenter presenter) {
            super(presenter);
        }

        public void setOrderInfo(OrderInfo orderInfo) {
            this.orderInfo = orderInfo;
        }

        @Override
        public void onResponseEx(TradePresenter presenter, Call<TzBaseResponse> call, Response<TzBaseResponse> response) {
            if (response == null || response.body() == null) {
                orderInfo.setUploadFlag(OrderInfo.UPLOAD_FAILED);
                presenter.updateOrInsert(orderInfo);
                return;
            }
            TzBaseResponse body = response.body();
            if (!body.isSuccess()) {
                orderInfo.setUploadFlag(OrderInfo.UPLOAD_FAILED);
                presenter.updateOrInsert(orderInfo);
                return;
            }
            // 上传成功 修改数据库
            orderInfo.setUploadFlag(OrderInfo.UPLOAD_SUCCESS);
            presenter.updateOrInsert(orderInfo);
        }

        @Override
        public void onFailureEx(TradePresenter presenter, Call<TzBaseResponse> call, Throwable throwable) {
            orderInfo.setUploadFlag(OrderInfo.UPLOAD_FAILED);
            presenter.updateOrInsert(orderInfo);
        }
    }

}
